﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using WiMo.Games.DirectDrawDisplay;

namespace WiMo.Games.Drawables
{
    public class FastBitmap
    {

        private Bitmap image;
        private BitmapData bitmapData;
        private int height;
        private int width;
        private byte[] rgbValues;
        bool locked = false;


        public int Height{ get{ return this.height; } }
        public int Width{ get { return this.width; } }

        public FastBitmap(int x, int y)
        {
            width = x;
            height = y;
            image = new Bitmap(x, y);
        }

        public byte[] GetAllPixels()
        {
            return rgbValues;
        }

        public void SetAllPixels(byte[] pixels)
        {
            rgbValues = pixels;
        }

        public Color GetPixel(int x, int y)
        {
            byte blue = rgbValues[(y * image.Width + x) * 3];
            byte green = rgbValues[(y * image.Width + x) * 3 + 1];
            byte red = rgbValues[(y * image.Width + x) * 3 + 2];

            return new Color(red, green, blue);
        }

        public void SetPixel(int x, int y, Color cIn)
        {
            rgbValues[(y * image.Width + x) * 3] = cIn.B;
            rgbValues[(y * image.Width + x) * 3 + 1] = cIn.G;
            rgbValues[(y * image.Width + x) * 3 + 2] = cIn.R;
        }

        public static implicit operator Image(FastBitmap bmp)
        {
            return bmp.image;
        }

        public static implicit operator Bitmap(FastBitmap bmp)
        {
            return bmp.image;
        }

        public void LockPixels()
        {
            LockPixels(new Rectangle(0, 0, image.Width, image.Height));
        }

        private void LockPixels(Rectangle area)
        {
            if (locked)
                return;

            locked = true;

            //bbitmapData = image.LockBits(area.ToDrawingRect(), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            IntPtr ptr = bitmapData.Scan0;
            int stride = bitmapData.Stride;
            int numBytes = image.Width * image.Height * 3;
            rgbValues = new byte[numBytes];
            Marshal.Copy(ptr, rgbValues, 0, numBytes);
        }

        public void UnlockPixels()
        {
            if (!locked)
                return;

            locked = false;

            Marshal.Copy(rgbValues, 0, bitmapData.Scan0, image.Width * image.Height * 3);

            image.UnlockBits(bitmapData);
        }
    }

}
